wayland: Allow grabless xdg_popups
authorCarlos Garnacho <carlosg@gnome.org>
Tue, 18 Oct 2016 17:18:14 +0000 (19:18 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 20 Oct 2016 09:41:59 +0000 (11:41 +0200)
xdg_shell v6 allows grabless popups, whose behavior is not that
different from override redirect windows with no grab to take
keyboard input (and pointer events outside).

This means we can relax the requirement to have a grab before
creating an xdg_popup. The warning is still useful to have so
people stop relying on gdk_window_show();gdk_device_grab() being
an ok pattern to popup a window, it's been moved to wayland
implementation of gdk_device_grab() instead, so we warn if trying
to grab a GDK_WINDOW_TEMP window that's already visible.

https://bugzilla.gnome.org/show_bug.cgi?id=771694

gdk/wayland/gdkdevice-wayland.c
gdk/wayland/gdkwindow-wayland.c

index f453df5b4d849267432739264841ee45203e708e..f139b77cae58ca8ee37154811c26cd9b60dc98e2 100644 (file)
@@ -740,6 +740,15 @@ gdk_wayland_device_grab (GdkDevice    *device,
   GdkWindow *prev_focus = gdk_wayland_device_get_focus (device);
   GdkWaylandPointerData *pointer = GDK_WAYLAND_DEVICE (device)->pointer;
 
+  if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP &&
+      gdk_window_is_visible (window))
+    {
+      g_warning ("Window %p is already mapped at the time of grabbing. "
+                 "gdk_seat_grab() should be used to simultanously grab input "
+                 "and show this popup. You may find oddities ahead.",
+                 window);
+    }
+
   if (prev_focus != window)
     device_emit_grab_crossing (device, prev_focus, window, GDK_CROSSING_GRAB, time_);
 
index bb55044de1dbd40f5229eb985c8cf43a2f0c40f9..f6b4b7bc8ee6a34cb9f60a2004781db91332a676 100644 (file)
@@ -2072,9 +2072,12 @@ gdk_wayland_window_create_xdg_popup (GdkWindow      *window,
 
   zxdg_positioner_v6_destroy (positioner);
 
-  gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
-  serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
-  zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial);
+  if (seat)
+    {
+      gdk_seat = gdk_display_get_default_seat (GDK_DISPLAY (display));
+      serial = _gdk_wayland_seat_get_last_implicit_grab_serial (gdk_seat, NULL);
+      zxdg_popup_v6_grab (impl->display_server.xdg_popup, seat, serial);
+    }
 
   wl_surface_commit (impl->display_server.wl_surface);
 
@@ -2123,18 +2126,6 @@ find_grab_input_seat (GdkWindow *window, GdkWindow *transient_for)
   return NULL;
 }
 
-static struct wl_seat *
-find_default_input_seat (GdkWindow *window)
-{
-  GdkDisplay *display;
-  GdkSeat *seat;
-
-  display = gdk_window_get_display (window);
-  seat = gdk_display_get_default_seat (display);
-
-  return gdk_wayland_seat_get_wl_seat (seat);
-}
-
 static gboolean
 should_be_mapped (GdkWindow *window)
 {
@@ -2330,16 +2321,6 @@ gdk_wayland_window_map (GdkWindow *window)
       else
         {
           grab_input_seat = find_grab_input_seat (window, transient_for);
-
-          if (!grab_input_seat)
-            {
-              g_warning ("No grabbed seat found, using the default one in "
-                         "order to map popup window %p. You may find oddities "
-                         "ahead, gdk_seat_grab() should be used to "
-                         "simultaneously grab input and show this popup",
-                         window);
-              grab_input_seat = find_default_input_seat (window);
-            }
         }
 
       if (!create_fallback)